#include <iostream>
#include <string_view>
#include <unordered_map>
#include <gtest/gtest.h>
using namespace std::literals;

std::unordered_map<std::string, std::string> dict;
// 如果需要实现全局的事件机制、需要创建一个自己的类，然后继承testing::Environment
// 然后重写SetUp和TearDown函数
class HashTestEnv : public testing::Environment
{
public:
    virtual void SetUp() override
    {
        std::cout << "测试前：提前准备测试数据\n";
        dict.insert({"hello", "你好"});
        dict.insert({"print", "打印"});
    }
    virtual void TearDown() override
    {
        std::cout << "测试后：清理测试数据\n";
        dict.clear();
    }
};
// TEST(hash_case_test, find)
// {
//     auto it = dict.find("hello");

//     ASSERT_NE(it, dict.end());
//     ASSERT_EQ(it->second, "你好");
// }

// TEST(hash_case_test, size)
// {
//     assert(true);
//     ASSERT_TRUE(dict.size() != 0);
// }

// class HashTestEnv1 : public testing::Test
// {
// public:
//     static void SetUpTestCase()
//     {
//         std::cout << "环境1第一个TEST之前调用" << std::endl;
//     }
//     static void TearDownTestCase()
//     {
//         std::cout << "环境1最后一个TEST之后调用" << std::endl;
//     }

// public:
//     std::unordered_map<std::string, std::string> dict1;
// };

// 每个TEST_F都会默认构造一个新的HashTestEnv1对象，所以size测试EQ才是成立的
// TEST_F(HashTestEnv1, insert_test)
// {
//     std::cout << "Env1, 中间insert测试" << std::endl;
//     dict1.insert({"hello", "你好"});
//     dict1.insert({"print", "打印"});
//     dict1.insert({"bye", "再见"});

//     auto it = dict1.find("hello");
//     ASSERT_NE(it, dict1.end());
// }

// TEST_F(HashTestEnv1, size)
// {
//     std::cout << "Env1, 中间size测试" << std::endl;
//     ASSERT_EQ(dict1.size(), 0);
// }

class HashTestEnv2 : public testing::Test
{
public:
    static void SetUpTestCase()
    {
        std::cout << "环境1第一个TEST之前调用" << std::endl;
    }
    static void TearDownTestCase()
    {
        std::cout << "环境1最后一个TEST之后调用" << std::endl;
    }

    virtual void SetUp() override
    {
        std::cout << "Env2 :提前准备测试数据" << std::endl;
        dict1.insert({"渣渣", "zhazha"});
        dict1.insert({"嘿嘿", "heihei"});
    }

    virtual void TearDown() override
    {
        std::cout << "Env2 : 销毁测试数据" << std::endl;
        dict1.clear();
    }

public:
    std::unordered_map<std::string, std::string> dict1;
};
// 根据输出可以看到TearDown和SetUp都被调用了两次，可以得出每一次TEST_F都会重新实例化一个对象
TEST_F(HashTestEnv2, insert_test)
{
    std::cout << "Env2:中间insert测试" << std::endl;
    dict1.insert({"C++", "cpp"});
    dict1.insert({"JAVA", "爪哇"});
    auto it = dict1.find("JAVA");
    ASSERT_EQ(it->second, "爪哇");
    ASSERT_EQ(dict1.size(), 4);
}

TEST_F(HashTestEnv2, size)
{
    std::cout << "Env2:中间size测试" << std::endl;
    ASSERT_EQ(dict1.size(), 2);
}

int main(int argc, char *argv[])
{
    // testing::AddGlobalTestEnvironment(new HashTestEnv);
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}